<template>
  <div class="m-table" ref="containerRef">
    <div ref="tableExtraRef" class="m-table__title" v-if="$slots.extra">
      <el-space wrap>
        <slot name="extra"></slot>
      </el-space>
    </div>

    <div
      class="tableBox"
      ref="tableBox"
      :style="setTableHeight ? 'height: calc(100vh - 385px);' : ''"
    >
      <!-- 设置表头显示列表 -->
      <div v-if="isopen" class="setColumnList">
        <div class="allCheckbox">
          <el-checkbox
            v-model="isAll"
            :indeterminate="isIndeterminate"
            label="all"
            size="large"
            @change="changAll"
          >
            全部
          </el-checkbox>
        </div>
        <div class="checkBoxList">
          <el-checkbox-group
            v-model="checkList"
            size="large"
            @change="handleCheckChange"
          >
            <div v-for="i in props.columns" :key="i.key">
              <el-checkbox :label="i.key">{{ i.label }}</el-checkbox>
            </div>
          </el-checkbox-group>
        </div>
      </div>

      <el-table
        class="m-table__main"
        :border="true"
        :stripe="true"
        :height="normalizedTableProps.height"
        v-bind="$attrs"
        :ref="selection.elTableRef"
        v-loading="props.loading || httpRes.loading"
        :data="(data as any[])"
        :row-key="props.rowKey"
        @selection-change="selection.handleSelectionChange"
        @header-dragend="headerDragendHandler"
      >
        <template v-if="props.selectKeys">
          <el-table-column
            type="selection"
            width="55"
            :selectable="props.setCheck"
            :reserve-selection="props.reserveSelection"
            fixed
          />
        </template>

        <template v-if="props.series">
          <el-table-column
            type="index"
            width="60"
            label="序号"
            v-bind="props.seriesAttrs"
            #default="{ $index }"
          >
            {{ indexStart + $index + 1 }}
          </el-table-column>
        </template>
        <el-table-column
          v-for="column in tableColumns"
          v-bind="column.attrs"
          :show-overflow-tooltip="!column.slot"
          :key="column.key"
          :prop="column.key"
          :label="column.label ?? column.key"
          :width="column.width"
          :fixed="column.fixed"
        >
          <template #header="{ column, $index }">
            <div v-show="false">{{ (column.minWidth = 200) }}</div>
            <div style="display: flex">
              <span class="headerLabel">{{ column.label ?? column.key }}</span>
              <div class="setColumn" @click="openSetColumn">
                <img
                  v-if="props.series && $index === tableColumns.length + 1"
                  src="@/assets/imgs/setIcon.png"
                />
                <img
                  v-if="!props.series && $index === tableColumns.length"
                  src="@/assets/imgs/setIcon.png"
                />
              </div>
            </div>
          </template>
          <template
            v-if="column.slot || column.customRender"
            #default="{ row, $index }"
          >
            <slot
              :name="column.key"
              :row="row"
              :index="$index"
              :value="getVal(row, column.key)"
              :width="getWidth(column)"
            >
              {{
                column.customRender
                  ? column.customRender(getVal(row, column.key), row, $index)
                  : getVal(row, column.key)
              }}
            </slot>
          </template>

          <template v-else #default="{ row }">
            {{
              [null, undefined, ''].includes(getVal(row, column.key))
                ? '--'
                : getVal(row, column.key)
            }}
          </template>

          <!-- <template v-else #default="{ row }">
            <TooltipBox
              :content="getVal(row, column.key)"
              :width="getWidth(column)"
            ></TooltipBox>
            <el-tooltip
              v-if="false && row[column.key] && row[column.key].length > 10"
              class="box-item"
              effect="dark"
              placement="top"
            >
              <template #content>
                <div>{{ getVal(row, column.key) }}</div>
              </template>
              <span class="lineFeed">{{
                row[column.key].slice(0, 10) + '...'
              }}</span>
            </el-tooltip>
            <span class="lineFeed" v-else>
              <span
                v-if="getVal(row, column.key) || getVal(row, column.key) === 0"
                >{{ getVal(row, column.key) }}</span
              >
              <span v-else>--</span>
            </span>
          </template> -->
        </el-table-column>
        <!-- 无数据显示 -->
        <template #empty>
          <div class="noData">
            <img src="@/assets/imgs/noData.png" alt="" />
            <div>暂无数据</div>
          </div>
        </template>
      </el-table>
    </div>
    <!-- 分页器 -->
    <div
      ref="paginationRef"
      v-if="props.paginationConfig"
      class="m-table__pagination"
    >
      <div class="m-table__pagination__total">
        共 {{ dataTotal }} 条记录
        <template v-if="dataTotal > 0">
          第 {{ paginationParams.currentPage }} /
          {{ Math.ceil(dataTotal / paginationParams.pageSize) }} 页
        </template>
      </div>
      <el-pagination
        background
        layout="prev, pager, next, sizes, jumper"
        v-bind="props.paginationConfig"
        v-model:currentPage="paginationParams.currentPage"
        v-model:page-size="paginationParams.pageSize"
        :page-sizes="props.paginationConfig.pageSizes"
        :total="dataTotal"
        @size-change="handleSizeChange"
      >
      </el-pagination>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, toRef } from 'vue'
import { getVal } from '@/utils'
import { tableProps, tableEmits } from './table'
import {
  usePagination,
  useHttpData,
  useSelection,
  useTableProps
} from './hooks'
import { watch } from 'vue'
// import TooltipBox from './tooltipBox/tooltipBox.vue'

defineOptions({
  name: 'MTable',
  inheritAttrs: false
})

const props = defineProps(tableProps)
const emit = defineEmits(tableEmits)

// data 内部分页
const { paginationParams, paginationData, indexStart } = usePagination(props)

const { containerRef, paginationRef, doHeight, normalizedTableProps } =
  useTableProps({
    height: toRef(props, 'height'),
    autoFitHeight: props.autoFitHeight,
    setTableHeight: props.setTableHeight
  })

// request http
const httpRes = useHttpData(props, paginationParams, () => {
  emit('update:isReload', false)
  emit('getData', httpRes.data)
})

const handleSizeChange = () => {
  paginationParams.currentPage = 1
}

// table 实际渲染的数据
const data = computed(() => httpRes.data || paginationData.value)

// selectkey
const selection = useSelection(props, data, (selectKeys) => {
  emit('update:selectKeys', selectKeys)
})

// total
const dataTotal = computed(() => httpRes.total || props.data.length)

//字段一行展示不换行
// function renderHeader({ column }: any) {
//   let span = document.createElement('span')
//   span.innerText = column.label
//   document.body.appendChild(span)
//   column.minWidth = span.getBoundingClientRect().width + 150
//   document.body.removeChild(span)
//   return h('span', column.label)
// }

const tableColumns: any = ref(props.columns)

// const tableColumns = computed({
//   get: () => {
//     return props.columns
//   },
//   set: (val) => {
//     return val
//   }
// })

const isopen = ref(false)
const checkList: any = ref([])
const isAll = ref(true)
const isIndeterminate = ref(false)
// 全选
function changAll(e: any) {
  if (e) {
    checkList.value = props.columns.map((i: any) => {
      return i.key
    })
  } else {
    checkList.value = []
  }
  isIndeterminate.value = false
}

// 默认全部展示
checkList.value = tableColumns.value.map((i: any) => {
  return i.key
})

// 打开列表弹窗
function openSetColumn() {
  isopen.value = !isopen.value
}

// 勾选改变表格
function handleCheckChange(e: any) {
  let newArr: any = []
  props.columns.forEach((i: any) => {
    if (e.includes(i.key)) {
      newArr.push(i)
    }
  })
  tableColumns.value = newArr

  if (e.length && e.length < props.columns.length) {
    isIndeterminate.value = true
  } else {
    isIndeterminate.value = false
  }
}

watch(checkList, (val) => {
  let newArr: any = []
  props.columns.forEach((i: any) => {
    val.forEach((j: any) => {
      if (i.key === j) {
        newArr.push(i)
      }
    })
  })
  tableColumns.value = newArr
})

onMounted(() => {
  doHeight()
})

// 拖拽
const rawColumnWidth = ref<Record<string, number>>({})
const headerDragendHandler = (
  newWidth: number,
  oldWidth: number,
  column: any
) => {
  const { rawColumnKey } = column
  rawColumnWidth.value[rawColumnKey] = newWidth
}

const getWidth = (column: any) => {
  const width =
    rawColumnWidth.value[column.key] || Math.max(column.minWidth, column.width)
  if (isNaN(width)) {
    return undefined
  }
  return width
}

defineExpose({
  tableRef: selection.elTableRef
})
</script>

<style lang="scss" scoped>
.m-table {
  .m-table__title {
    display: flex;
    margin-bottom: 20px;
    // justify-content: flex-end;
  }
  .m-table__main {
    // 用表头控制 margin 空表布局会多出 20
    // margin: 20px 0;
    width: 100%;
    :deep(.el-table__header th) {
      color: #5a5a5a;
      background-color: #fafafa;
    }
    :deep(th),
    :deep(td) {
      padding: 15px 0;
    }
  }
  .m-table__pagination {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-top: 10px;
    &__total {
      color: #0000006d;
    }
  }
}
.lineFeed {
  white-space: nowrap;
}
.tableBox {
  // height: calc(100vh - 385px);
  position: relative;
}

.setColumn {
  margin-left: auto;
  height: 23px;
  img {
    cursor: pointer;
    width: 25px;
    height: 25px;
  }
}
.setColumnList {
  // padding: 5px;
  border: 1px solid #e8e8e8;
  width: 260px;
  height: 530px;
  max-height: 100%;
  overflow-y: auto;
  background: #fff;
  position: absolute;
  top: 62px;
  right: 0;
  z-index: 999;
  overflow-x: hidden;
  :deep(.el-checkbox__label) {
    font-size: 18px !important;
  }
}

.allCheckbox {
  padding: 5px;
  width: 100%;
  border-bottom: 1px solid #ccc;
}
.checkBoxList {
  padding: 5px;
}

:deep(.headerLabel),
:deep(.el-table__cell) {
  font-size: 16px;
}

// 前往 =》跳至
:deep(.el-pagination__goto) {
  display: none;
}
:deep(.el-pagination__jump) {
  &::before {
    content: '跳至';
    margin-right: 8px;
  }
}

:deep(.el-table__column-resize-proxy) {
  border-width: 2px;
  border-color: #327dd3;
}

// table header sort
:deep(.is-sortable.el-table__cell .cell) {
  display: flex;
  align-items: center;
}

:deep(.el-popper.is-dark) {
  max-width: 300px;
}
.noData {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  img {
    width: 260px;
    height: 260px;
  }
  div {
    font-family: CN-Normal, CN-Normal;
    font-weight: 400;
    font-size: 16px;
    color: #999999;
  }
}
:deep(.el-table--border .el-table__cell) {
  border-right: unset!important;
}
</style>
